<template>
  <view class="relative bg-white vip-recharge">
    <nav-bar color="white" bg-color="black" title="充值" show-back></nav-bar>
    <view class="content flex flex-col flex-auto">
      <!-- 会员基本信息 -->
      <view class="vip-info flex items-center">
        <view
          ><u-image
            :src="customerInfo.faceUrl"
            mode="aspectFill"
            width="100rpx"
            height="100rpx"
            radius="10rpx"
          ></u-image
        ></view>
        <info-panel class="flex-auto" ref="refInfoPanel" :config="infoConfig" />
      </view>
      <!-- 充值表单 -->
      <view class="recharge-form">
        <u-form ref="refRecharge" :model="formData" :rules="formRules" label-width="8rem" label-position="top">
          <!-- 套餐卡充值 -->
          <view class="flex justify-between" v-if="cardInfo.membershipCardType == '2'">
            <u-form-item label="开通套餐:" prop="membershipPackageName" required>
              <view class="w-full">
                <u-search
                  shape="square"
                  placeholder="请选择套餐"
                  v-model="formData.membershipPackageName"
                  search-icon-size="15rpx"
                  action-text="选择"
                  @custom="openSelector"
                  :disabled="false"
                ></u-search>
              </view>
            </u-form-item>
            <u-form-item label="有效时间:" required prop="startDate">
              <view class="w-full">
                <uni-datetime-picker type="daterange" v-model="packTimeRange" @change="changeDataSelect" />
              </view>
            </u-form-item>
          </view>

          <view class="flex justify-between" v-if="cardInfo.membershipCardType == '2'">
            <u-form-item label="用餐次数:">
              <view class="w-full">
                <u-input type="number" disabled v-model="packageInfo.monthNum"></u-input>
              </view>
            </u-form-item>

            <u-form-item label="价格:">
              <view class="w-full">
                <u-input type="digit" disabled v-model="packageInfo.price"></u-input>
              </view>
            </u-form-item>
          </view>

          <!-- 会员卡充值 -->
          <view class="flex justify-between" v-if="cardInfo.membershipCardType == '1'">
            <u-form-item label="充值金额（元）:" prop="chargeMoney" required>
              <view class="my-5rpx w-full">
                <u-input type="digit" v-model="formData.chargeMoney" placeholder="请输入金额"></u-input>
              </view>
            </u-form-item>
            <!-- <u-form-item label="历史余额（元）:">
              <view class="my-5rpx w-full">
                <u-input v-model="details.money" disabled placeholder="请输入金额" font-size="10rpx"></u-input>
              </view>
            </u-form-item> -->
            <u-form-item label="商户账户余额（元）:">
              <view class="my-5rpx w-full">
                <u-input v-model="details.businessMoney" disabled placeholder="请输入金额" font-size="10rpx"></u-input>
              </view>
            </u-form-item>
          </view>
          <view class="flex justify-between">
            <u-form-item label="赠送金额（元）:" prop="giveMoney">
              <view class="w-full">
                <u-input type="digit" v-model="formData.giveMoney" placeholder="请输入金额"></u-input>
              </view>
            </u-form-item>
            <u-form-item label="赠送积分:" prop="giveIntegral">
              <view class="w-full">
                <u-input
                  v-model="formData.giveIntegral"
                  placeholder="请输入积分"
                  type="number"
                  font-size="10rpx"
                ></u-input>
              </view>
            </u-form-item>
          </view>
        </u-form>
      </view>

      <view class="rounded-md flex mt-10rpx p-15rpx bg-slate-100 items-center justify-between">
        <view class="flex text-base">
          <text class="mr-10rpx block">实收金额: </text>
          <text class="font-bold text-red-500 text-lg"> ￥{{ actualReceivedAmount }} </text>
        </view>
        <view class="text-base flex items-center">
          <text class="whitespace-nowrap mr-10rpx">支付方式:</text>
          <u-button
            :disabled="!formData.chargeMoney"
            type="error"
            size="large"
            custom-style="padding:10rpx 20rpx;margin-right:10rpx"
            @click="openScanBoxPay"
            >扫码盒子</u-button
          >

          <u-button
            :disabled="!formData.chargeMoney"
            type="warning"
            size="large"
            custom-style="padding:10rpx 20rpx;"
            @click="openCashPayPopup"
            >现金支付</u-button
          >
        </view>
      </view>
    </view>

    <!-- 扫码支付弹窗 && 消息通知弹窗 （// TODO 这里有点乱了，应该把两个弹窗分开） -->
    <resultPopup ref="refCommonPopup" :show-icon="false">
      <template #default="{ result }">
        <view v-if="result.dataType == 'cash'" class="mt-20rpx flex-col items-center justify-center text-center">
          <template v-if="result.content">
            <text class="block text-base py-10rpx"> {{ result.content }}</text>
          </template>
          <template v-else>
            <text class="block text-base py-10rpx text-gray-400"> 找零 </text>
            <text class="block font-bold"> {{ result.giveChange || "0.00" }} 元 </text>
          </template>
        </view>
        <view class="flex-col" v-else-if="result.dataType == 'scan'">
          <scanPay skipPayment :show-paytype="false" :qrSize="200" @pay-finish="onScanPayFinish">
            <template #title>
              <view class="flex items-center justify-center text-center">
                <text class="block text-base"> 待收款金额: </text>
                <text class="block text-base font-bold text-red-500"> ￥{{ actualReceivedAmount }} </text>
              </view>
            </template>
          </scanPay>
        </view>
      </template>
      <template #confirm="{ config }">
        <view class="btns flex" v-if="config.state != 'success'">
          <view class="btns-item" @click="refCommonPopup.close()">
            <text class="btns-item-txt"> {{ config.dataType == "cash" ? "确定" : "取消支付" }} </text>
          </view>
        </view>
      </template>
    </resultPopup>

    <!-- 现金支付弹窗 -->
    <u-popup
      ref="refCashPayPopup"
      :show="isShowCashKeybord"
      mode="center"
      round="10rpx"
      @close="isShowCashKeybord = false"
      close-on-click-overlay
    >
      <cashPay skipPayment :modelMoney="actualReceivedAmount" @pay-finish="onCashPayFinish"> </cashPay>
    </u-popup>

    <!-- 弹窗提示 - 主要用于显示一些错误信息 -->
    <resultPopup ref="refResultPopup"> </resultPopup>

    <!-- 套餐选择器 -->
    <kui-selector
      ref="kuiSelector"
      @submitItem="onSubmit"
      popupMode="right"
      :popupStyle="{
        height: '100%',
        maxWidth: '50vw',
      }"
    ></kui-selector>
  </view>
</template>
<script lang="ts" setup>
import { onLoad, onReady } from "@dcloudio/uni-app";
import { reactive, ref, onMounted, onBeforeUnmount, inject, computed } from "vue";
import { getAccountInfoById, getCustomerById, rechargeMembership, getCardByCustomerId } from "@/api";
import { formatMoney, getFieldValueByThisDict } from "@/utils/util";
import resultPopup from "@/components/common-popup/result-popup.vue";
import scanPay from "../subOrder/place-order/components/com-pay-dialog/scan-pay.vue";
import cashPay from "../subOrder/place-order/components/com-pay-dialog/cash-pay.vue";
import { useStore } from "vuex";
import KuiSelector from "@kingon/kui-view/components/kui-selector/kui-selector.vue";
import { getDetailsByCustomerId, getVIPAccountByPhysicalCard } from "./utils";

import dayjs from "dayjs";

const store = useStore();

const pageStatus = reactive({
  loading: false,
});

// 页面传递的参数
const pagePam = {
  id: "",
};
onLoad((e: any) => {
  console.log("onLoad:>", e);
  if (e.id) pagePam.id = e.id;
  // loadSysDict(["sys_payType"]);
});

const details = ref({});
const accountDetails = ref({});

// const { pageChannel } = inject("$globalData");

const getAccountDetailsByPhysicalCard = async (physicalCardNumber: string) => {
  try {
    const info = await getVIPAccountByPhysicalCard(physicalCardNumber);
    accountDetails.value = info;
    // 获取到客户id后，再获取客户信息 和卡信息

    // 并附加一些会员信息，以便 info-panel 组件使用

    // 从 前一个页面的数据中获取到客户信息
    const vipSubInfo = {
      // vaCard: pageChannel.vaCard,
      vipLevel: info.vipLevel,
      // 办卡类型：1普通办卡2套餐办卡  (注：membershipCardTypeName 为自定义字段)
      membershipCardTypeName: cardInfo.value.membershipCardType == 2 ? "套餐办卡" : "普通办卡",
      vipCardNum: cardInfo.value.logicalCardNumber,
      // 充值单号 (CZ + 当前11位时间戳)
      rechargeOrderNum: "CZ" + new Date().getTime(),
      // 商户(历史)账户余额
      moneyText: "￥" + formatMoney(info.businessMoney),
      // 赠送账户余额
      giveMoneyText: "￥" + formatMoney(info.giveMoney),
    };

    Object.assign(customerInfo.value, vipSubInfo);

    refInfoPanel.value.updateValues(infoConfig, customerInfo.value, "-");

  } catch (error) {
    console.error(error);
  }
}

const getPageData = async (updateAccountInfo = true) => {
  console.log("getPageData:>", pagePam);
  pageStatus.loading = true;
  try {
    const result = await getDetailsByCustomerId(pagePam.id);
    details.value = result.accountInfo;
    cardInfo.value = result.cardInfo;
    customerInfo.value = result.customerInfo;

    formData.membershipCardType = cardInfo.value?.membershipCardType;
   

    // orderList.value = data.records;
    pageStatus.loading = false;

    if (updateAccountInfo) {
      getAccountDetailsByPhysicalCard(cardInfo.value.physicalCardNumber);
    }
  } catch (error) {
    pageStatus.loading = false;
    console.error(error);
  }
};

const customerInfo = ref({});
const refInfoPanel = ref();
// 更新 信息面板组件
const infoConfig = [
  {
    // title: "基本信息",
    children: [
      {
        type: "txt-double",
        title: ["姓名：", /*  "充值单号：", */ "VA卡："],
        key: ["customerName", /* "rechargeOrderNum", */ "vaCard"],
        dict: [],
      },
      {
        type: "txt-double",
        title: ["会员卡等级：", "办卡类型："],
        key: ["vipLevel", "membershipCardTypeName"],
        dict: [],
      },
      {
        type: "txt-double",
        title: ["手机号：", "商户账户余额："],
        key: ["customerPhone", "moneyText"],
        dict: [],
      },
      {
        type: "txt-double",
        title: ["会员卡号：", "赠送账户余额："],
        key: ["vipCardNum", "giveMoneyText"],
        dict: [],
      },
    ],
  },
];

const refResultPopup = ref();

// 获取到会员卡信息
const cardInfo = ref({
  membershipCardType: "",
});

onMounted(async () => {
  await getPageData();
});

onBeforeUnmount(() => {});

// 充值表单
const formData = reactive({
  chargeMoney: 0,
  amountMoney: 0,
  customerInformationId: "", // 会员信息id  取 details
  giveMoney: 0,
  memberCard: "", //  会员卡（物理卡号）取 details
  payType: "4", //  （固定）	充值方式(2微信3支付宝4现金6刷卡12现金-微信13现金-支付宝)
  paySource: "2", // 充值平台，1是PC，2是APP
  rechargeId: "",
  orderNumbers: "",
  giveIntegral: 0,
  deposit: 0,
  membershipCardType: "1",
  //----- 套餐 ---
  packageId: "" /** 	套餐id (提交字段) */,
  membershipPackageId: "" /** 	套餐id */,
  membershipPackageName: "" /** 	套餐名称 */,
  startDate: dayjs().format("YYYY-MM-DD HH:mm:ss") /** 	开始日期 */,
  endDate: dayjs().add(31, "day").format("YYYY-MM-DD HH:mm:ss") /** 	结束日期 */,
});
// 表单规则
const formRules = {
  chargeMoney: {
    pattern: /^\d+(\.\d+)?$/,
    required: true,
    message: "请填输入充值金额",
    trigger: ["blur", "change"],
  },
};

onReady(() => {
  // refRecharge.value?.setRules(formRules);
});

// 实收金额
const actualReceivedAmount = computed(() => {
  // 充值金额 + 补缴押金
  const money = (Number(formData.chargeMoney) || 0) + (Number(formData.deposit) || 0);
  return formatMoney(money);
});

const refRecharge = ref();
// 支付弹窗
const refCommonPopup = ref();
const refCashPayPopup = ref();

const openScanBoxPay = async () => {
  await refRecharge.value?.validate();
  const popupConfig = {
    title: "扫码支付",
    content: "",
    cancelText: "取消支付",
    autoClose: false,
    //----- 自定义数据
    dataType: "scan",
  };

  refCommonPopup.value.open(popupConfig);
};

const isShowCashKeybord = ref(false);

const openCashPayPopup = async () => {
  await refRecharge.value?.validate();
  isShowCashKeybord.value = true;
  console.log("openCashPayPopup:");
};

const onCashPayFinish = async ({ type, money }) => {
  // 关闭弹窗
  isShowCashKeybord.value = false;

  const modelMoney = Number(actualReceivedAmount.value);
  const trueMoney = Number(money); /** 实收 */
  const { businessId } = store.getters.businessInfo;
  try {
    uni.showLoading({ title: "", mask: true });
    // 调用充值接口

    // 生成充值单号 & 订单号
    formData.rechargeId = "CZ" + new Date().getTime();
    formData.orderNumbers = formData.rechargeId;
    // 补充会员信息
    formData.customerInformationId = details.value?.customerId;
    formData.memberCard = cardInfo.value?.physicalCardNumber;
    // 实收金额
    formData.amountMoney = trueMoney;
    // 补充 cstmId
    formData.cstmId = businessId; //商户id

    const pam = { ...formData, deviceCode: store.getters.deviceId };

    // 如果是 套餐卡充值，则需要特殊参数

    // 如果是 套餐卡充值，则需要特殊参数
    if (cardInfo.value?.membershipCardType == "2") {
      pam.packageId = packageInfo.businessServiceItemId;
      pam.packageName = packageInfo.packageTypeName;
    }

    const { data, success } = await rechargeMembership(pam);
    if (!success) throw new Error("充值失败");
    uni.hideLoading();
    // 刷新会员信息
    await getPageData();
  } catch (error: any) {
    console.error("catch - recharge.vue", error);
    uni.hideLoading();
    const popupConfig = {
      title: "充值失败",
      closeInAfter: 5000,
      showIcon: true,
      type: "fail",
      content: error.message,
      // 自定义信息
      state: "fail",
      dataType: "cash",
    };
    refCommonPopup.value.open(popupConfig);
    return;
  }

  isShowCashKeybord.value = false;

  // 如果是现金收款，而且收款金额大于应收，则提示找零
  console.log("收款结束：", { type, money });

  if (trueMoney > modelMoney) {
    // 现金支付找零
    console.log("收款金额大于应收，请找零:", trueMoney - modelMoney, "元", `${trueMoney} - ${modelMoney}`);
    const popupConfig = {
      title: "收款成功",
      content: "",
      closeInAfter: 600000,
      showIcon: true,
      // 自定义信息
      dataType: "cash",
      state: "success",
      giveChange: `${(trueMoney - modelMoney).toFixed(2)}`,
    };
    refCommonPopup.value.open(popupConfig);
  } else {
    // 其他情况显示商户支付成
    const popupConfig = {
      title: "收款成功",
      closeInAfter: 5000,
      showIcon: true,
      content: "",
      // 自定义信息
      state: "success",
      dataType: "none",
    };
    refCommonPopup.value.open(popupConfig);
  }
};

const onScanPayFinish = ({ payBean, result }) => {
  console.log("onScanPayFinish:", { payBean, result });
  switch (payBean.status) {
    case "success":
      console.log("支付组件获取付款吗成功");
      // 发起充值支付
      rechargePaymentLogic(payBean.payCode, payBean.codeType);
      break;
    case "fail":
      console.log("发起支付失败");
      const popupConfig = {
        title: "发起支付失败",
        closeInAfter: 5000,
        showIcon: true,
        type: "fail",
        content: " ",
        // 自定义信息
        state: "fail",
        dataType: "none",
      };
      refCommonPopup.value.open(popupConfig);
      break;
    case "cancel":
      console.log("取消支付");

      break;
    default:
  }
};

// 充值支付逻辑
const rechargePaymentLogic = async (payAuthCode: string, codeType: string) => {
  const { businessId } = store.getters.businessInfo;
  // console.log("rechargePaymentLogic:", { businessId, store });
  try {
    uni.showLoading({ title: "", mask: true });
    // 调用充值接口

    // 生成充值单号 & 订单号
    formData.rechargeId = "CZ" + new Date().getTime();
    formData.orderNumbers = formData.rechargeId;
    // 补充会员信息
    formData.customerInformationId = details.value?.customerId;
    formData.memberCard = cardInfo.value?.physicalCardNumber;
    // 实收金额
    formData.amountMoney = Number(actualReceivedAmount.value);
    // 补充 cstmId
    formData.cstmId = businessId; //商户id

    const pam = {
      ...formData,
      deviceCode: store.getters.deviceId
    };

    // 加上支付授权码
    if (payAuthCode) {
      pam.authCode = payAuthCode;
      pam.payType = codeType == "alipay" ? 3 : 2; // 支付方式 2微信3支付宝）
    }

    // pam.deviceCode = ""

    // 如果是 套餐卡充值，则需要特殊参数
    if (cardInfo.value?.membershipCardType == "2") {
      pam.packageId = packageInfo.businessServiceItemId;
      pam.packageName = packageInfo.packageTypeName;
    }

    const { data, success } = await rechargeMembership(pam);
    if (!success) throw new Error("充值失败");
    uni.hideLoading();
    refCommonPopup.value.open({
      title: "充值成功",
      closeInAfter: 15000,
      showIcon: true,
      type: "success",
      content: " ",
      // 自定义信息
      state: "success",
      dataType: "none",
    });
    // 刷新会员信息
    await getPageData();

    console.log("开卡绑定会员成功", data);
  } catch (error) {
    uni.hideLoading();
    const popupConfig = {
      title: "充值失败",
      showIcon: true,
      type: "fail",
      content: error.message,
      // 自定义信息
      state: "fail",
      dataType: "none",
    };
    refCommonPopup.value.open(popupConfig);
    console.error("充值失败", error);
    // 抛出异常
    throw new Error("充值失败");
  }
};

// 套餐选择器
const kuiSelector = ref();
const openSelector = (e) => {
  const config = {
    action: "/kingon-service-base/businessServiceItem/packageIpage",
    pam: { dataType: 13 },
    navigationBar: ["套餐名称", "套餐类型", "价格（元）", "用餐次数", "累计方式", "适用餐别"],
    labelKey: ["itemName", "packageType", "price", "monthNum", "accumulationMethod", "mealType"],
    labelType: ["text", "text", "text", "text"],
    valueKey: "itemName",
    showSearch: true,
    showNavigationBar: true,
    searchKey: "itemName",
    format: (keyName, value, type) => {
      if (keyName === "packageType") {
        return getFieldValueByThisDict("packageType", value, dicts);
      } else if (keyName === "mealType" && value) {
        const typs = value.split(",");
        return typs.map((v) => getFieldValueByThisDict("mealType", v, dicts)).join(" | ");
      } else if (keyName === "accumulationMethod") {
        return getFieldValueByThisDict("accumulationMethod", value, dicts);
      }
      return value;
    },
  };
  kuiSelector.value.show(config);
};

const packTimeRange = ref([
  dayjs().format("YYYY-MM-DD HH:mm:ss"),
  dayjs().add(1, "months").format("YYYY-MM-DD HH:mm:ss"),
]);
const changeDataSelect = (e) => {
  console.log("changeDataSelect>>", e);
  if (e.length == 0) {
    // 清空
    formData.startDate = "";
    formData.endDate = "";
  } else {
    // [formData.startDate, formData.endDate] = e;
    formData.startDate = dayjs(e[0]).format("YYYY-MM-DD HH:mm:ss");
    formData.endDate = dayjs(e[1]).format("YYYY-MM-DD HH:mm:ss");
  }
  packTimeRange.value = e;
};

// 当前选择的套餐类型
const packageInfo = reactive({
  packageTypeName: "",
  businessServiceItemId: "",
  price: 0,
});
const onSubmit = (data) => {
  // console.log("onSubmit", data);
  if (data) {
    // packageInfo.value = data.origin.item;
    Object.assign(packageInfo, data.origin.item);
    formData.membershipPackageId = packageInfo.businessServiceItemId;
    formData.membershipPackageName = data.value;
    packageInfo.packageTypeName = getFieldValueByThisDict("packageType", packageInfo.packageType, dicts);
    formData.chargeMoney = packageInfo.price;
  }
};

// 其他自定义字典
const dicts = reactive({
  packageType: [
    {
      dictLabel: "日套餐",
      dictValue: "day",
    },
    {
      dictLabel: "月套餐",
      dictValue: "month",
    },
  ],
  mealType: [
    {
      dictLabel: "早餐",
      dictValue: 1,
    },
    {
      dictLabel: "午餐",
      dictValue: 2,
    },
    {
      dictLabel: "晚餐",
      dictValue: 3,
    },
    {
      dictLabel: "下午茶",
      dictValue: 4,
    },
    {
      dictLabel: "夜宵",
      dictValue: 5,
    },
  ],
  accumulationMethod: [
    {
      dictLabel: "全部清零",
      dictValue: 1,
    },
    {
      dictLabel: "全部累计",
      dictValue: 2,
    },
    {
      dictLabel: "部分累计",
      dictValue: 3,
    },
  ],
});
</script>
<style lang="scss" scoped>
.vip-recharge {
  height: 100%;
  box-sizing: border-box;

  .content {
    width: 70%;
    margin: auto;
    height: 100%;
    padding: 10rpx 20rpx;

    ::v-deep .u-input {
      padding: 5rpx !important;

      .u-input__content {
        .u-input__content__field-wrapper__field {
          font-size: 10rpx !important;
        }
      }
    }
  }
}

.btns-item {
  background-color: #efefef;
  padding: 5rpx 20rpx;
  border-radius: 5rpx;
  margin: 0rpx 15rpx;
  font-size: 12rpx;

  .btns-item-txt {
    font-size: 10rpx;
    padding: 5rpx 10rpx;
  }

  ::v-deep .u-button {
    padding: 2rpx 10rpx;
  }
}
</style>
